/* eslint-disable max-params */
import { YFnParams, YForm, YItemConfig } from '../../interface';
function bindHandler(
  config: YItemConfig,
  mergeData: { [key: string]: any },
  handler?: (
    params: { [key: string]: any },
    mergeData: { [key: string]: any }
  ) => { [key: string]: any }
) {
  const value = config.bind || {};
  return (options: YFnParams) => {
    const result = typeof value === 'function' ? value(options) : value;
    return handler ? handler(result, mergeData) : { ...result, ...mergeData };
  };
}

function fieldHandler(
  config: YItemConfig,
  key: string,
  handler?: (data: any) => any
) {
  const value = config[key];
  return (options: YFnParams) => {
    const result = typeof value === 'function' ? value(options) : value;
    return handler ? handler(result) : result;
  };
}

const interception: {
  itemConfig?: { [key: string]: (config: YItemConfig) => YItemConfig };
  validate?: (form: any, callback: (isValid: boolean) => void) => void;
  event?: Function;
  get?: (form: YForm, prop: string, value: any, config: YItemConfig) => any;
  set?: (form: YForm, prop: string, value: any, config: YItemConfig) => any;
  props?: (props: { [key: string]: any }, vm: any) => { [key: string]: any };
  rule?: (rule: any, form: YForm) => any;
} = {
  itemConfig: {
    '*'(config: YItemConfig) {
      return config;
    },
    radioGroup(config) {
      config.optionHandler = (options: { [key: string]: any }[]) =>
        options.map((option) => ({
          type: config.optionType || 'radio',
          nodes: option.label,
          bind: {
            label: option.value,
          },
        }));
      return config;
    },
    checkboxGroup(config) {
      config.optionHandler = (options: { [key: string]: any }[]) =>
        options.map((option) => ({
          type: config.optionType || 'checkbox',
          nodes: option.label,
          bind: {
            label: option.value,
          },
        }));
      return config;
    },
    date(config) {
      config.bind = bindHandler(config, { type: 'date' });
      return config;
    },
    dateRange(config) {
      config.bind = bindHandler(
        config,
        { type: 'daterange' },
        (params, mergeData) => {
          mergeData.startPlaceholder = '开始时间';
          mergeData.endPlaceholder = '结束时间';
          return { ...params, ...mergeData };
        }
      );
      return config;
    },
    weekRange(config) {
      config.bind = bindHandler(config, { type: 'week' });
      return config;
    },
    monthRange(config) {
      config.bind = bindHandler(
        config,
        { type: 'monthrange' },
        (params, mergeData) => {
          mergeData.startPlaceholder = '开始时间';
          mergeData.endPlaceholder = '结束时间';
          return { ...params, ...mergeData };
        }
      );
      return config;
    },
    yearRange(config) {
      config.bind = bindHandler(config, { type: 'year' });
      return config;
    },
    dateTimeRange(config) {
      config.bind = bindHandler(
        config,
        { type: 'datetimerange' },
        (params, mergeData) => {
          mergeData.startPlaceholder = '开始时间';
          mergeData.endPlaceholder = '结束时间';
          return { ...params, ...mergeData };
        }
      );
      return config;
    },
  },
  validate(form: any, callback: (isValid: boolean) => void) {
    return form.validate(callback);
  },
  set(vm: any, prop: string, value: any, config) {
    return value;
  },
  get(form: YForm, prop: string, value: any, config: YItemConfig) {
    return value;
  },
  rule(YRule: any, form: any) {
    const rule = { ...YRule };
    if (rule.validator && typeof rule.validator === 'function') {
      const validatorHandler = rule.validator;
      rule.validator = (rule: any, ...args: any[]) => {
        validatorHandler(form, ...args);
      };
    }
    return rule;
  },
};

export default interception;
